/*********************************************************************
 * 版权所有(C)
 * 项目代号:     
 * 文件名称:     Handler.cpp
 * 运行平台:     Linux
 * 编译环境:     C编译器--GCC
 * 程序语言:     c++
 * 作   者：     lingcong
 * 内容摘要:     仿Android的Handler，消息链表处理句柄，用于处理发过来的消息并进行延时处理
 * 完成日期:     2019年5月15日
 ***********************************************************************/
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "Handler.h"

Handler* Handler::_pIo = NULL;

Handler::Handler()
{
    pCmsgLink = new CmsgLink();
    if (pCmsgLink == NULL)
    {
        printf("create pCmsgLink failed\r\n");
    }

    pthread_mutex_init(&mMutex, NULL);

    pthread_cond_init(&mConditional, NULL);

    isHandlerLoopStart = 0;
}

Handler::Handler(const Handler& orig)
{

}

Handler::~Handler()
{

}

/**********************************************************************
 * 函数名称： Handler::getInstance()
 * 功能描述： 获取Handler实例
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 ***********************************************************************/
Handler* Handler::getInstance()
{
    if (NULL != _pIo) return _pIo;
    _pIo = new Handler();
    return _pIo;
}

/**********************************************************************
 * 函数名称： init
 * 功能描述： 初始化操作,实例化后必须先调用；
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 ***********************************************************************/
void Handler::init(void)
{

}

/**********************************************************************
 * 函数名称： void *_handlerLoop(void *pArg)
 * 功能描述： handler接收线程回调函数；
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 ***********************************************************************/
void *_handlerLoop(void *pArg)
{
    //printf("Handler recvLoop up\r\n");
    ((Handler *) pArg)->handlerLoop(pArg);
}

/**********************************************************************
 * 函数名称： handlerLoop(void *pArg)
 * 功能描述： handler接收线程
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 ***********************************************************************/
void Handler::handlerLoop(void *pArg)
{
    int count = 0, i, len;
    char *pData = NULL;
    
    void *arg;
    Callback callback;

    while (NULL == pCmsgLink)
    {
        pCmsgLink = new CmsgLink();
        sleep(1);
    }

    //printf("handlerLoop start\r\n");

    while (1)
    {
        pthread_mutex_lock(&mMutex);
        if (pCmsgLink->getNodeNum() == 0)
        {
            //printf("handler loop wait\r\n");
            pthread_cond_wait(&mConditional, &mMutex);
        }
        pthread_mutex_unlock(&mMutex);

        count = pCmsgLink->tickNode(10);
        //printf("handler,time out1\r\n");
        for (i = 0; i < count; i++)
        {
            //len = pCmsgLink->getTimeoutNodeData((void **) &pData);
            len = pCmsgLink->getTimeoutNodeData((void **) &pData, &arg, &callback);

            if(callback != NULL){
                callback(arg, pData, len);
                arg = NULL;
                callback = NULL;
            }

            //释放pData内存
            if(pData != NULL){
                free(pData);
                pData = NULL;
            }
        }

        usleep(10 * 1000); //10ms 一次循环
    }
}

/**********************************************************************
 * 函数名称： startHandlerTask()
 * 功能描述： 启动handler接收线程；
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 ***********************************************************************/
void Handler::startHandlerTask()
{
    if (0 == isHandlerLoopStart)
    {
        int ret = pthread_create(&handlerTask, NULL, _handlerLoop, (void *) this);
        if (0 != ret)
        {
            printf("Handler::startHandlerTask fail to create _handlerLoop thread !\n");
        }
        isHandlerLoopStart = 1;
    }
}

/**********************************************************************
 * 函数名称： Handler::sendMsgDelay(int id, int timeout, void *pData, int pDatalen)
 * 功能描述： 发送延迟处理消息
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 ***********************************************************************/
int Handler::sendMsgDelay(int id, int timeout, void *pData, int pDatalen)
{
    int ret = -1;

    if (pCmsgLink != NULL)
    {
        ret = pCmsgLink->addNode(id, timeout, pData, pDatalen);
    }

    pthread_mutex_lock(&mMutex);
    pthread_cond_signal(&mConditional);
    pthread_mutex_unlock(&mMutex);

    return ret;
}

/**********************************************************************
 * 函数名称： Handler::sendMsgDelay
 * 功能描述： 发送延迟处理消息
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 ***********************************************************************/
int Handler::sendMsgDelay(int id, int timeout, void *pData, int pDatalen, void *arg, Callback callback)
{
    int ret = -1;

    if (pCmsgLink != NULL)
    {
        ret = pCmsgLink->addNode(id, timeout, pData, pDatalen, arg, callback);
    }

    pthread_mutex_lock(&mMutex);
    pthread_cond_signal(&mConditional);
    pthread_mutex_unlock(&mMutex);

    return ret;
}

/**********************************************************************
 * 函数名称： Handler::removeMsg
 * 功能描述： 删除延时链表的一个消息，因为此消息已不用处理
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 ***********************************************************************/
int Handler::removeMsg(int id)
{
    int ret = -1;

    if (pCmsgLink != NULL)
    {
        ret = pCmsgLink->deleteNode(id);
    }

    return ret;
}

/**********************************************************************
 * 函数名称： dprintf
 * 功能描述： 调试打印内容
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 ***********************************************************************/
void Handler::dprintf(char *pData, int len)
{
    int i = 0;

    for (; i < len; i++)
    {
        printf("0x%02x ", pData[i]);
    }
    printf("\r\n");
}

/**********************************************************************
 * 函数名称： getMsgNum
 * 功能描述： 获取消息队列长度
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 ***********************************************************************/
int Handler::getMsgNum(void)
{
    return pCmsgLink->getNodeNum();
}

/**********************************************************************
 * 函数名称： getMsgById
 * 功能描述： 通过id获取消息，并删除该消息
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 ***********************************************************************/
int Handler::getMsgById(int id, void *pData, int maxLen)
{
    return pCmsgLink->getNodeDataById(id, pData, maxLen);
}

bool Handler::isNodeIdExist(int id)
{
    return pCmsgLink->isNodeIdExist(id);
}

